package com.uminho.egendme;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import org.json.JSONException;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.markupartist.android.widget.ActionBar;
import com.markupartist.android.widget.ActionBar.Action;
import com.uminho.exceptions.DestroyException;
import com.uminho.exceptions.InvalidJSonException;
import com.uminho.exceptions.InvalidOAuthParametersError;
import com.uminho.exceptions.InvalidOAuthTokenError;
import com.uminho.exceptions.NotAllowedError;
import com.uminho.exceptions.OAuthServiceFailureError;
import com.uminho.exceptions.SaveException;
import com.uminho.http.InternalStorage;
import com.uminho.http.Webservice;
import com.uminho.objects.Bookmark;
import com.uminho.objects.Service;
import com.uminho.tools.Disponibilidades;

/****
 * c* egendme/Favorites DESCRIPTION Classe responsável por oferecer suporte à
 * actividade Favorites
 * 
 **** 
 */

public class Favorites extends Activity {

	/*
	 * private String[] descriptions = null; private String[] titles = null;
	 * private Drawable[] images = null; private long[] serviceIds = null;
	 * private long[] bookmarksIds = null;
	 */
	ServiceDialog sD=null;
	private ListView lister1;
	ProgressDialog myProgressDialog = null;
	Handler messages;
	boolean offline = false;
	private Service s;
	private Bookmark selectedBookmark = null;
	private ItemsAdapter itemsAdapter;
	private List<Bookmark> services = null;

	/** Called when the activity is first created. */

	/****
	 * f* Favorites/onCreate DESCRIPTION Método executado para criar a
	 * actividade INPUTS Estado da aplicação RESULT Actividade criada
	 **** 
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.favorites);
		ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
		actionBar.setHomeAction(new Action() {

			public void performAction(View view) {
				finish();
			}

			public int getDrawable() {
				return R.drawable.icon1;
			}
		});
		actionBar.setTitle(R.string.favorites);
		/*
		 * actionBar.setOnLogoClickListener(new OnClickListener(){ public void
		 * onClick(View v) { Intent i = new Intent(Favorites.this,
		 * Dashboard.class); startActivity(i); } });
		 */
		final Drawable imageAux = this.getResources().getDrawable(
				R.drawable.icon);

		myProgressDialog = ProgressDialog.show(Favorites.this,
				getString(R.string.loading), getString(R.string.getFavorites),
				true);
		messages = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 1) {
					if (offline)
						Toast.makeText(Favorites.this,
								getString(R.string.working_offline), 3000)
								.show();
					myProgressDialog.dismiss();
					initListView(services);
				} else if (msg.what == -1) {
					// token/auth error
					myProgressDialog.dismiss();
					Toast.makeText(Favorites.this,
							getString(R.string.autentication_error),
							Toast.LENGTH_LONG).show();
					setResult(2);
					InternalStorage.goLoggin(Favorites.this);
				} else if (msg.what == -3) {
					myProgressDialog.dismiss();
					Toast.makeText(Favorites.this,
							getString(R.string.no_favorites), Toast.LENGTH_LONG)
							.show();
					initFavoritesEmpty();
					// finish();
				} else if (msg.what == 15) {
					myProgressDialog.dismiss();
					sD = new ServiceDialog(Favorites.this, s,
							selectedBookmark.getBookmarkId(),
							new DialogEventListener() {

								public void onRemove(Dialog dialog,
										long bookmarkId) {
									dialog.dismiss();
									Webservice w = Webservice.getInstance();

									try {
										if (w.delBookmark(bookmarkId)) {
											if(itemsAdapter.removeService(bookmarkId)==0){
												View v = findViewById(R.id.LinearLayoutNotEmptyFavorites);
												v.setVisibility(View.GONE);
												v = findViewById(R.id.LinearLayoutEmptyFavorites);
												v.setVisibility(View.VISIBLE);
												
												Toast toast = Toast.makeText(
														Favorites.this, R.string.favoriteRemoved,
														Toast.LENGTH_SHORT);
												toast.show();
											}
											
										}
									} catch (Exception e) {
										return;
									}

									
									
								}
							});
					sD.show();
					
				} else /* if(msg.what==-2) */{
					// connection error
					myProgressDialog.dismiss();
					Toast.makeText(Favorites.this,
							getString(R.string.impossiblereachtheserver),
							Toast.LENGTH_LONG).show();
				}

			}
		};
		new Thread() {

			@Override
			public void run() {

				ArrayList<Bookmark> array = null;
				/*
				 * try { Webservice w = Webservice.getInstance();
				 * //w.addBookmark(Long.valueOf(1));
				 * //w.addBookmark(Long.valueOf(2));
				 * w.addBookmark(Long.valueOf(3));
				 * w.addBookmark(Long.valueOf(4));
				 * w.addBookmark(Long.valueOf(5));
				 * w.addBookmark(Long.valueOf(6));
				 * w.addBookmark(Long.valueOf(7));
				 * //w.addBookmark(Long.valueOf(8));
				 * //w.delBookmark(Long.valueOf(6));
				 * //w.delBookmark(Long.valueOf(7));
				 * //w.delBookmark(Long.valueOf(8));
				 * //w.delBookmark(Long.valueOf(9)); } catch (Exception e) { //
				 * TODO Auto-generated catch block Log.d("addd app",
				 * ""+e.getClass().toString()); }
				 */

				try {

					Webservice w = Webservice.getInstance();
					array = w.getBookmarks();

					if (array != null && array.size() > 0) {
						InternalStorage.saveBookmarks(array);

					}
				} catch (InvalidOAuthTokenError e) {
					messages.sendEmptyMessage(-1);
					Log.d("Favorites", "token error loading bookmarks");
					return;
				} catch (InvalidOAuthParametersError e) {
					messages.sendEmptyMessage(-1);
					Log.d("Favorites", "autentication error loading bookmarks");
					return;
				} catch (Exception e) {
					if (array == null || array.size() <= 0) {
						array = InternalStorage.readBookmarks();
						offline = true;
					}
					if (array == null || array.size() <= 0) {

						Log.d("Favorites", e.getClass().toString());
						messages.sendEmptyMessage(-2);
						Log.d("Favorites", "error loading bookmarks");
						return;
					}
				}

				if (array == null || array.size() <= 0) {
					array = new ArrayList<Bookmark>();
					messages.sendEmptyMessage(-3);
					Log.d("Favorites", "Array de bookmarks null!!!!");
					return;

				}
				//itemsAdapter.addServices(array);
				services=array;
				// myProgressDialog.dismiss();
				messages.sendEmptyMessage(1);

			}

		}.start();

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Log.d("Favorites", "actvityRequest " + requestCode + " " + resultCode);
		if (resultCode == 2) {
			Log.d("Favorites", "finish");
			this.finish();
		}
		if (resultCode == 4) {
			if(sD != null && sD.isShowing()) sD.dismiss();
			Log.d("Favorites", "finish");
			this.finish();
		} else if (resultCode == 3) {
			Log.d("Favorites", "refresh");
			Intent refresh = new Intent(this, Favorites.class);
			startActivity(refresh);
			this.finish();
		}

	}

	/****
	 * f* Favorites/initFavoritesEmpty DESCRIPTION Método executado para iniciar
	 * a lista de favoritos quando vazia INPUTS Dados dos favoritos RESULT
	 * Favoritos vazia construída
	 **** 
	 */
	private void initFavoritesEmpty() {
		LinearLayout emptyFavorites = (LinearLayout) findViewById(R.id.LinearLayoutEmptyFavorites);
		emptyFavorites.setVisibility(LinearLayout.VISIBLE);
		ListView listView = (ListView) findViewById(R.id.list);
		listView.setVisibility(ListView.INVISIBLE);

	}

	/****
	 * f* Favorites/initListView DESCRIPTION Método executado para iniciar a
	 * lista de favoritos INPUTS Dados dos favoritos RESULT Favoritos
	 * construídos
	 **** 
	 */
	private void initListView(List<Bookmark> services) {
		LinearLayout notEmptyFavorites = (LinearLayout) findViewById(R.id.LinearLayoutNotEmptyFavorites);
		notEmptyFavorites.setVisibility(LinearLayout.VISIBLE);

		lister1 = (ListView) findViewById(R.id.list);
		lister1.setVisibility(View.VISIBLE);
		if (services != null && services.size() != 0) {
			itemsAdapter = new ItemsAdapter(Favorites.this, services);

			lister1.setAdapter(itemsAdapter);
			/**
			 * 
			 * Listview touch Listener!
			 */
			lister1.setOnItemClickListener(new AdapterView.OnItemClickListener() {

				public void onItemClick(AdapterView<?> parent, View view,
						int position, long id) {

					selectedBookmark = (Bookmark) parent
							.getItemAtPosition(position);
					final long idS = selectedBookmark.getServiceId();
					myProgressDialog = ProgressDialog.show(Favorites.this,
							getString(R.string.loading),
							getString(R.string.getService), true);
					myProgressDialog.show();
					new Thread() {
						@Override
						public void run() {
							Webservice w = Webservice.getInstance();
							try {
								s = w.getService(idS);
								/*
                                 * Aqui são carregadas as disponibilidades
                                 * As excepções não precisam de ser tratadas
                                 */
                                try{
                                GregorianCalendar g = new GregorianCalendar();
                                Disponibilidades.serviceBusyDays=w.getDisponibilidadeAnual( g.get(GregorianCalendar.YEAR), s.getId());
                                }catch(Exception ex){ex.printStackTrace();}
                                
								messages.sendEmptyMessage(15);
							} catch (NumberFormatException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (MalformedURLException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (InvalidJSonException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (ParseException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (IOException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (InvalidOAuthParametersError e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (InvalidOAuthTokenError e) {
								messages.sendEmptyMessage(-1);
								e.printStackTrace();
							} catch (OAuthServiceFailureError e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (NotAllowedError e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (URISyntaxException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (JSONException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (SaveException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							} catch (DestroyException e) {
								messages.sendEmptyMessage(0);
								e.printStackTrace();
							}

						}
					}.start();

				}
			});
		} else {

		}
	}

	/*
	 * @Override protected void onDestroy(){ try { this.finish();
	 * super.onDestroy(); } catch (Throwable e) { // TODO Auto-generated catch
	 * block e.printStackTrace(); } }
	 */

	/****
	 * c* egendme/ItemsAdapter DESCRIPTION Classe responsável por oferecer
	 * suporte à ListView Favoritos
	 * 
	 **** 
	 */
	private class ItemsAdapter extends BaseAdapter {
		/*
		 * String[] descriptions; String[] titles; Drawable[] images; long[]
		 * serviceIds;
		 */
		List<Bookmark> services;

		/*
		 * public ItemsAdapter(Context context, int textViewResourceId, String[]
		 * descriptions, String[] titles,Drawable[] imgs, long[] serviceIds) {
		 * this.titles=titles; this.descriptions = descriptions;
		 * this.images=imgs; this.serviceIds=serviceIds;
		 * 
		 * }
		 */

		public ItemsAdapter(Context context, List<Bookmark> services) {
			this.services = new ArrayList<Bookmark>(services);

		}

		/****
		 * f* ItemsAdapter/getView DESCRIPTION Método executado para iniciar
		 * cada favorito INPUTS Dados do favorito RESULT Vista do favorito
		 * concluída
		 **** 
		 */
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			TextView mDescription;
			TextView mTitle;
			ImageView image;
			View view = convertView;

			Bookmark s = services.get(position);

			if (view == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				view = vi.inflate(R.layout.favorites_row, null);

			}
			image = (ImageView) view.findViewById(R.id.image);
			if (s.getAvatar() != null)
				image.setImageDrawable(s.getAvatar());
			else
				image.setImageDrawable(view.getResources().getDrawable(
						R.drawable.empty_avatar));

			mTitle = (TextView) view.findViewById(R.id.favorite_row_title);
			mTitle.setText(s.getTitle());
			mDescription = (TextView) view
					.findViewById(R.id.favorite_row_description);
			mDescription.setText(s.getDescription());

			// Log.d("Favorites", "tit: "+titles[position]);

			return view;
		}

		/****
		 * f* ItemsAdapter/getCount DESCRIPTION Método executado para receber o
		 * numero de favoritos RESULT Recebido o numero de Favoritos
		 **** 
		 */
		public int getCount() {
			return services.size();
		}

		/****
		 * f* ItemsAdapter/getView DESCRIPTION Método executado para receber a
		 * vista de um favorito INPUTS Índice do favorito RESULT Vista do
		 * favorito
		 **** 
		 */
		public Object getItem(int position) {
			return services.get(position);
		}

		/****
		 * f* ItemsAdapter/getView DESCRIPTION Método executado para receber o
		 * indice de um favorito INPUTS Vista do favorito RESULT Indice do
		 * favorito
		 **** 
		 */
		public long getItemId(int position) {
			return services.get(position).getBookmarkId();
		}

		public void addServices(List<Bookmark> services) {
			this.services.addAll(services);
			this.notifyDataSetChanged();
		}

		public int removeService(long id) {

			Iterator<Bookmark> i = services.iterator();
			Bookmark b;
			while (i.hasNext()) {
				// Do something
				b = i.next();
				if (b.getBookmarkId() == id)
					i.remove();
			}

			this.notifyDataSetChanged();
			return services.size();
		}
	}

}
